package myutil.mylist;

import java.util.Iterator;

/**
 *
 * @author Hlib_Babii
 * @param <T> type of stored elements
 */
public interface MyList<T> extends Iterable<T> {
    
    /**
     * Appends the specified element to the end of the list.
     * @param e element to be added
     */
    void add(T e);
    
    /**
     * Inserts the specified element at the specified position in this list
     * and shifts the element currently at that position
     * (if any) and any subsequent elements to the right (adds one to their
     * indices).
     * @param index index at which the specified element is to be inserted
     * @param e element to be inserted
     * @throws IndexOutOfBoundsException if the index is out of range
     */
    void add(int index, T e);
    
    /**
     * Appends all of the elements in the specified collection to the end of
     * this list, in the order they are in the array.
     * @param c the array whose elements are to be appended
     */
    void addAll(T[] c);
    
    /**
     * Inserts all of the elements in the specified array into this
     * list at the specified position and shifts the
     * element currently at that position (if any) and any subsequent
     * elements to the right (increases their indices).  The new elements
     * will appear in this list in the order that they are in the array.
     *
     * @param index index at which to insert the first element from the
     *              specified array
     * @param c array containing elements to be added to this list 
     * @throws IndexOutOfBoundsException if the index is out of range
     */
    void addAll(int index, T[] c);
    
    /**
     * Returns the element at the specified position in this list.
     *
     * @param index index of the element to return
     * @return the element at the specified position in this list
     * @throws IndexOutOfBoundsException if the index is out of range 
     */
    T get(int index);
    
    /**
     * Removes the element at the specified position in this list (optional
     * operation).  Shifts any subsequent elements to the left (subtracts one
     * from their indices).  Returns the element that was removed from the
     * list.
     *
     * @param index the index of the element to be removed
     * @return the element previously at the specified position
     * @throws MyIndexOutOfBoundsException if the index is out of range
     */
    T remove(int index);
    
    /**
     * Removes all the elements from this list.
     */
    void clear();
    
    /**
     * checks whether this list is empty
     * @return true when this list contains no elements, false otherwise
     */
    boolean isEmpty();
    
    /**
     * Replaces the element at the specified position in this list with the
     * specified element.
     *
     * @param index index of the element to replace
     * @param e element to be stored at the specified position
     * 
     * @throws NullPointerException if the specified element is null and
     *         this list does not permit null elements
     * @throws MyIndexOutOfBoundsException if the index is out of range
     */
    void set(int index, T e);
    
    /**
     * Returns the index of the first occurrence of the specified element
     * in this list, or -1 if this list does not contain the element.
     *
     * @param o element to search for
     * @return the index of the first occurrence of the specified element in
     *         this list, or -1 if this list does not contain the element
     * @throws NullPointerException if the specified element is null
     */
    int indexOf(Object o);
    
    /**
     * returns the number of elements in this list
     * @return the number of elements in this list
     */
    int size();
    
    /**
     * Returns an array containing all of the elements in this list in proper
     * sequence (from first to last element).
     *
     * The returned array will be "safe" in that no references to it are
     * maintained by this list.  (In other words, this method must
     * allocate a new array even if this list is backed by an array).
     * The caller is thus free to modify the returned array.
     *
     * @return an array containing all of the elements in this list in proper
     *         sequence
     */
    Object[] toArray();
    
    /**
     * Returns an iterator over the elements in this list in proper sequence.
     *
     * @return an iterator over the elements in this list in proper sequence
     */
    @Override
    Iterator<T> iterator();
}
